package yl.hs.bmipfull.service.report.impl;

import com.google.common.collect.Maps;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yl.hs.bmipfull.daos.production.IProductShipOrderDao;
import yl.hs.bmipfull.pojo.production.BrickShipOrderModel;
import yl.hs.bmipfull.pojo.production.ProductShipOrderEntity;
import yl.hs.bmipfull.pojo.salemanage.BuildProjectInfoEntity;
import yl.hs.bmipfull.pojo.vehiclemanage.TruckInfoEntity;
import yl.hs.bmipfull.service.finance.IBrickShipSettleService;
import yl.hs.bmipfull.service.production.IProductShipOrderService;
import yl.hs.bmipfull.service.report.ISalesStatisticService;
import yl.hs.bmipfull.service.salemanage.IBuildProjectInfoService;
import yl.hs.bmipfull.service.salemanage.ICustomerInfoService;
import yl.hs.bmipfull.service.vehiclemanage.ITruckInfoService;
import yl.hs.bmipfull.utils.HsApp;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.report.BrickSalesStatisticListVO;
import yl.hs.bmipfull.viewmodels.report.SalesStatisticListVO;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 张凯
 * @apiNote 销售统计-service实现
 * @since 2022/2/22 9:04 上午 创建
 */
@Service
public class SalesStatisticServiceImpl implements ISalesStatisticService {

    @Autowired
    IProductShipOrderDao productShipOrderDao;
    @Autowired
    IProductShipOrderService productShipOrderService;

    @Autowired
    IBuildProjectInfoService projectInfoService;

    @Autowired
    ICustomerInfoService customerService;
    
    @Autowired
    ITruckInfoService truckInfoService;
    @Autowired
    private IBrickShipSettleService brickShipSettleService;
    @Override
    public List<Map<String, Object>> productSaleReport(PageQuery pageQuery,String productCateSn) throws Exception {
        List<Map<String,Object>> result=new ArrayList<>();
        //获取根据产品编号分组的数据集
        List<ProductShipOrderEntity> oneList =productShipOrderDao.queryGroupByProductSN(pageQuery.getQuery(),productCateSn,null,(List<Integer>)pageQuery.getQuery().get("states"));
        for (var entity: oneList) {
            Map<String,Object> map=new HashMap<>();
            Map<String,Object> map2=new HashMap<>();
            if(entity.getProductSN()!=null&& !"".equals(entity.getProductSN())){
                pageQuery.getQuery().put("productSN",entity.getProductSN());
            }
            //获取根据产品编号查询的数据集
            var twoList=productShipOrderService.queryList(pageQuery,productCateSn);
            double sumNetWeight=0.0;
            double sumQuantity=0.0;
            for(var item:twoList){
                if(item.getNetWeight()!=null){
                    sumNetWeight+=Double.parseDouble(item.getNetWeight().toString());
                    sumQuantity+=Double.parseDouble(item.getQuantity().toString());
                }

            }
            //数据处理
            map.put("productSN",entity.getProductSN());
            map.put("productCate",entity.getProductCate());
            map.put("productName",entity.getProductName());
            map.put("productSpec",entity.getProductSpec());
            List<Object> resultList=new ArrayList<>();
            map2.put("productSN",entity.getProductSN());
            map2.put("productCate",entity.getProductCate());
            map2.put("productName",entity.getProductName());
            map2.put("productSpec",entity.getProductSpec());
            map2.put("packWay",entity.getPackWay());
            map2.put("sumNetWeight",(double) Math.round(sumNetWeight * 100) / 100);
            map2.put("sumQuantity",(double) Math.round(sumQuantity * 100) / 100);
            map2.put("carNumber",twoList.size());
            map2.put("shipmentReviewWeight",entity.getShipmentReviewWeight());
            map2.put("shipmentReviewQuantity",entity.getShipmentReviewQuantity());
            resultList.add(map2);
            map.put("reportList",resultList);

            result.add(map);
        }
        return result;
    }
    @Override
    public List<Map<String, Object>> queryProjectStatistic(PageQuery pageQuery, String productCateSn) throws Exception {
        List<Map<String, Object>> result = new ArrayList<>();
        //查询所有满足条件的发货单
        List<ProductShipOrderEntity> productShipOrderList = productShipOrderService.queryList(pageQuery, productCateSn);
        //查询工地sn集合
        Set<String> projectSet = productShipOrderList.stream().map(ProductShipOrderEntity::getProjectSN).collect(Collectors.toSet());
        //组装数据
        projectSet.forEach(t -> {
                   BuildProjectInfoEntity projectInfo = projectInfoService.findBySn(t);
                   if (projectInfo != null) {
                       Map<String, Object> project = projectInfo.toMap();
                    //拼接reportList
                    List<SalesStatisticListVO> statisticList = new ArrayList<>();
                    productShipOrderList.stream().filter(n -> n.getProjectSN().equals(t)).forEach(shipOrder ->{
                        List<SalesStatisticListVO> tempVO = statisticList.stream().filter(v -> shipOrder.getTaskSN().equals(v.getTaskSn()) ||

                                ((shipOrder.getCustomerName().equals(v.getCustomerName())) &&
                                        shipOrder.getProductSN().equals(v.getProductSn()) &&
                                        (shipOrder.getProductTags() != null
                                                && shipOrder.getProductTags().equals(v.getProductTags()))
                                        // 有数据为空处理
                                        && (shipOrder.getProductSpec()==null?"":shipOrder.getProductSpec()).equals((v.getProductSpec()==null?"":v.getProductSpec()))

                                )).toList();
                        setSaleStatistic(statisticList, shipOrder, tempVO);
                    });
                    project.put("reportList",statisticList);
                    result.add(project);
                   }
                }
            );
         return result;
        }



    @Override
    public List<Object> queryCustomerAnalysis(PageQuery query,String sn) {
        try {
            List<Object> result = new ArrayList<>();
            var products = productShipOrderService.queryList(query,sn);
            Set<String> collect = products.stream().map(ProductShipOrderEntity::getCustomerSN).collect(Collectors.toSet());
            collect.forEach(t->{
                BigDecimal totolnetwight= BigDecimal.valueOf(0);
                BigDecimal totolque = BigDecimal.valueOf(0);
                List<SalesStatisticListVO> list = new ArrayList<>();
                val customerInfo = customerService.findBySN(t);
                if(customerInfo==null){
                    return;
                }
                val toList = products.stream().filter(c -> c.getCustomerSN().equals(customerInfo.getSn())).toList();
                Function<ProductShipOrderEntity, List<Object>> compositeKey = personRecord ->
                        Arrays.asList(personRecord.getProductCate(), personRecord.getProductName(),personRecord.getProductSpec(),personRecord.getProjectName(),personRecord.getProductTags(),personRecord.getBuildPosition());
                Map<Object, List<ProductShipOrderEntity>> map = toList.stream().collect(Collectors.groupingBy(compositeKey));
                map.keySet().forEach(key -> {
                    BigDecimal netwight= BigDecimal.valueOf(0);
                    BigDecimal que = BigDecimal.valueOf(0);
                    BigDecimal sale= BigDecimal.valueOf(0);
                    var listVale = map.get(key);
                    for (var item:listVale
                    ) {
                        netwight = netwight.add(item.getNetWeight());
                        que = que.add(item.getQuantity());
                        sale = sale.add(item.getSalesVolume());
                    }
                    var value= map.get(key).get(0);
                    list.add(new SalesStatisticListVO(value.getCustomerName(), value.getProjectName(), value.getBuildPosition(), sale, netwight, que, value.getPackWeight(), value.getPackWay(), value.getPackUnit(), value.getProductName(), value.getProductCate(), value.getProductCateSN(), value.getTaskSN(), value.getProductSN(),value.getProductTags(),listVale.size(),value.getProductSpec()));
                });
                var customer = customerInfo.toMap();
                customer.put("reportList",list);
                customer.put("totleTrulck",toList.size());
                for (var item:toList
                ) {
                    totolnetwight = totolnetwight.add(item.getNetWeight());
                    totolque = totolque.add(item.getQuantity());
                }
                customer.put("totolnetwight",totolnetwight);
                customer.put("totolque",totolque);
                result.add(customer);
            });
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    public List<Map<String, Object>> queryBrickProjectAnalysis(PageQuery pageQuery) {
        List<Map<String, Object>> result = new ArrayList<>();
        //查询所有满足条件的发货单
        pageQuery.getQuery().put("groupField","productSN,customerSN,projectSN");
        List<BrickShipOrderModel> productShipOrderList = brickShipSettleService.brickSaleStatistics(pageQuery);
        //查询工地sn集合
        Set<String> projectSet = productShipOrderList.stream().map(BrickShipOrderModel::getProjectSN).collect(Collectors.toSet());
        //组装数据
        projectSet.forEach(t -> {
            BuildProjectInfoEntity projectInfo = projectInfoService.findBySn(t);
            if (projectInfo != null) {
                Map<String, Object> project = projectInfo.toMap();
                //拼接reportList
                List<BrickSalesStatisticListVO>  statisticList = new ArrayList<>();
                productShipOrderList.stream().filter(n -> n.getProjectSN().equals(t)).forEach(shipOrder -> {
                    List<BrickSalesStatisticListVO> tempVO = statisticList.stream().filter(v -> ((shipOrder.getCustomerName().equals(v.getCustomerName()))  && shipOrder.getProductSN().equals(v.getProductSn())
//                                            (shipOrder.getProductTags() != null && shipOrder.getProductTags().equals(v.getProductTags())) &&
//                                            shipOrder.getProductSpec().equals(v.getProductSpec())
                    )).toList();
                    setBrickSaleStatistic(statisticList, shipOrder, tempVO);
                });
                // 工地发货车数
                pageQuery.getQuery().put("projectSN", projectInfo.getSn());
                project.put("countCars", brickShipSettleService.brickCountCars(pageQuery));
                project.put("reportList", statisticList);
                result.add(project);
            }
        });
        return result;
    }
    private void setBrickSaleStatistic(List<BrickSalesStatisticListVO> statisticList, BrickShipOrderModel model, List<BrickSalesStatisticListVO> paramList) {
        BrickSalesStatisticListVO brickSalesStatisticListVO;
        if (!(paramList != null && paramList.size() > 0)) {
            brickSalesStatisticListVO = new BrickSalesStatisticListVO();
        } else {
            brickSalesStatisticListVO = paramList.get(0);
        }
        brickSalesStatisticListVO.setProductName(model.getProductName());
        brickSalesStatisticListVO.setProductName(model.getProductName());
        brickSalesStatisticListVO.setSumQuantity(model.getQuantity());
        brickSalesStatisticListVO.setSumVolume(model.getCountVolume());
        brickSalesStatisticListVO.setShipmentReviewQuantity(model.getShipmentReviewQuantity());
        brickSalesStatisticListVO.setShipmentReviewVolume(model.getCountShipmentReviewVolume());
        brickSalesStatisticListVO.setTrainNum(model.getCountCars());
        if (!(paramList != null && paramList.size() > 0)) {
            statisticList.add(brickSalesStatisticListVO);
        }
    }

    @Override
    public Map<String, Object> queryBrickProductAnalysis(PageQuery pageQuery) {
        Map<String, Object> resultMap = Maps.newHashMap();
        List<Map<String, Object>> result = new ArrayList<>();
        //获取根据产品编号分组的数据集
        pageQuery.getQuery().put("groupField","productSN,warehouseName");
        var user = HsApp.getCurrent();
        if(user!=null){
            pageQuery.getQuery().put("types", user.getType()==null?0:user.getType());
        }
        List<BrickShipOrderModel> oneList = brickShipSettleService.brickSaleStatistics(pageQuery);
        for (var entity : oneList) {
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> map2 = new HashMap<>();
            if (entity.getProductSN() != null && !"".equals(entity.getProductSN())) {
                pageQuery.getQuery().put("productSN", entity.getProductSN());
            }
            map.put("productSN", entity.getProductSN());
            map.put("productCate", entity.getProductCate());
            map.put("productName", entity.getProductName());
            map.put("productSpec", entity.getProductSpec());
            map.put("warehouseName", entity.getWarehouseName());
            List<Object> resultList = new ArrayList<>();
            map2.put("productSN", entity.getProductSN());
            map2.put("productCate", entity.getProductCate());
            map2.put("productName", entity.getProductName());
            map2.put("productSpec", entity.getProductSpec());
            map2.put("sumQuantity", entity.getCountQuantity());
            map2.put("sumVolume", entity.getCountVolume());
            map2.put("carNumber", entity.getCountCars());
            map2.put("shipmentReviewQuantity", entity.getCountShipmentReviewQuantity());
            map2.put("shipmentReviewVolume", entity.getCountShipmentReviewVolume());
            resultList.add(map2);
            map.put("reportList", resultList);
            result.add(map);
        }
        resultMap.put("data", result);
        // 总共发货车数
        resultMap.put("countCars", brickShipSettleService.brickCountCars(pageQuery));
        return resultMap;
    }

    @Override
    public List<Object> queryBrickCustomerAnalysis(PageQuery query) {
        try {
            List<Object> result = new ArrayList<>();
            query.getQuery().put("groupField","productSN,customerSN,shipmentReviewPrice");
            var user = HsApp.getCurrent();
            if(user!=null){
                query.getQuery().put("types", user.getType()==null?0:user.getType());
            }
            var products = brickShipSettleService.brickSaleStatistics(query);
            Set<String> collect = products.stream().map(BrickShipOrderModel::getCustomerSN).collect(Collectors.toSet());
            collect.forEach(t->{
                List<BrickSalesStatisticListVO> list = new ArrayList<>();
                var customerInfo = customerService.findBySN(t);
                if(customerInfo==null){
                    return;
                }
                var toList = products.stream().filter(c -> c.getCustomerSN().equals(customerInfo.getSn())).toList();
                Function<BrickShipOrderModel, List<Object>> compositeKey = personRecord ->
                        Arrays.asList(personRecord.getProductCate(), personRecord.getProductName(),personRecord.getProductSpec(),personRecord.getShipmentReviewPrice(),"","");
                Map<Object, List<BrickShipOrderModel>> map = toList.stream().collect(Collectors.groupingBy(compositeKey));
                map.keySet().forEach(key -> {
                    var value= map.get(key).get(0);
                    var data=new BrickSalesStatisticListVO();
                    data.setCustomerName(value.getCustomerName());
                    data.setProductName(value.getProductName());
                    data.setProductCateName(value.getProductCate());
                    data.setProductSn(value.getProductSN());
                    data.setTrainNum(value.getCountCars());
                    data.setSumVolume(value.getCountVolume());
                    data.setSumQuantity(value.getCountQuantity());
                    data.setShipmentReviewQuantity(value.getCountShipmentReviewQuantity());
                    data.setShipmentReviewVolume(value.getCountShipmentReviewVolume());
                    data.setShipmentReviewPrice(value.getShipmentReviewPrice());
                    list.add(data);
                });
                var customer = customerInfo.toMap();
                customer.put("reportList",list);
                // 客户发货车数
                query.getQuery().put("customerSN", customerInfo.getSn());
                customer.put("countCars", brickShipSettleService.brickCountCars(query));
                result.add(customer);
            });
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    public List<Map<String, Object>> queryTruckSaleReport(PageQuery pageQuery, String productCateSn) throws Exception {
        List<Map<String, Object>> result = new ArrayList<>();
        //查询所有满足条件的发货单
        List<ProductShipOrderEntity> productShipOrderList = productShipOrderService.queryList(pageQuery, productCateSn);
//查询工地sn集合
        Set<String> truckSnSet = productShipOrderList.stream().map(ProductShipOrderEntity::getTruckSN).collect(Collectors.toSet());
        truckSnSet.forEach(truckSn -> {
           TruckInfoEntity truckInfo = truckInfoService.findBySn(truckSn);
            if (truckInfo != null) {
                Map<String, Object> truckMap = truckInfo.toMap();
                //拼接reportList
                List<SalesStatisticListVO> statisticList = new ArrayList<>();

                productShipOrderList.stream().filter(n -> n.getTruckSN().equals(truckSn)).forEach(shipOrder ->{
                    List<SalesStatisticListVO> tempVO = statisticList.stream().filter(v ->
                                    shipOrder.getProjectName().equals(v.getProjectName()) &&
                                            shipOrder.getCustomerName().equals(v.getCustomerName())
                            ).toList();
                    setSaleStatistic(statisticList, shipOrder, tempVO);
                });
                truckMap.put("reportList",statisticList);
                result.add(truckMap);
            }
       });
        return result;
    }

    /**
     * 将当前发货单的值参与统计
     * @param statisticList 统计明细信息
     * @param shipOrder 发货单
     * @param tempVO 临时的一条统计信息（可能为空）
     */
    private void setSaleStatistic(List<SalesStatisticListVO> statisticList, ProductShipOrderEntity shipOrder, List<SalesStatisticListVO> tempVO) {
        if (tempVO != null && tempVO.size() > 0){
            SalesStatisticListVO salesStatisticListVO = tempVO.get(0);
            salesStatisticListVO.setNetWeight(shipOrder.getNetWeight().add(salesStatisticListVO.getNetWeight()));
            salesStatisticListVO.setShipmentReviewWeight((shipOrder.getShipmentReviewWeight()== null ? BigDecimal.ZERO :shipOrder.getShipmentReviewWeight()).add(salesStatisticListVO.getShipmentReviewWeight()== null ? BigDecimal.ZERO :salesStatisticListVO.getShipmentReviewWeight()));
            salesStatisticListVO.setShipmentReviewWeight((shipOrder.getShipmentReviewQuantity()==null?BigDecimal.ZERO:shipOrder.getShipmentReviewQuantity()));
            salesStatisticListVO.setSalesVolume((shipOrder.getSalesVolume()== null ? BigDecimal.ZERO :shipOrder.getSalesVolume()).add(salesStatisticListVO.getSalesVolume()== null ? BigDecimal.ZERO :shipOrder.getSalesVolume()));
            salesStatisticListVO.setTrainNum(salesStatisticListVO.getTrainNum() + 1);
            salesStatisticListVO.setQuantity(shipOrder.getQuantity().add(salesStatisticListVO.getQuantity()));
        } else {
            SalesStatisticListVO salesStatisticVO = new SalesStatisticListVO();
            salesStatisticVO.setBuildPosition(shipOrder.getBuildPosition());
            salesStatisticVO.setCustomerName(shipOrder.getCustomerName());
            salesStatisticVO.setNetWeight(shipOrder.getNetWeight());
            salesStatisticVO.setPackUnit(shipOrder.getPackUnit());
            salesStatisticVO.setPackWay(shipOrder.getPackWay());
            salesStatisticVO.setPackWeight(shipOrder.getPackWeight());
            salesStatisticVO.setProductCate(shipOrder.getProductCate());
            salesStatisticVO.setProjectName(shipOrder.getProjectName());
            salesStatisticVO.setProductName(shipOrder.getProductName());
            salesStatisticVO.setProductTags(shipOrder.getProductTags());
            salesStatisticVO.setProductSn(shipOrder.getProductSN());
            salesStatisticVO.setProductCateSn(shipOrder.getProductCateSN());
            salesStatisticVO.setQuantity(shipOrder.getQuantity());
            salesStatisticVO.setShipmentReviewWeight(shipOrder.getShipmentReviewWeight() == null ? BigDecimal.ZERO :shipOrder.getShipmentReviewWeight());
            salesStatisticVO.setShipmentReviewQuantity(shipOrder.getShipmentReviewQuantity() == null ? BigDecimal.ZERO :shipOrder.getShipmentReviewQuantity());
            salesStatisticVO.setSalesVolume(shipOrder.getSalesVolume()== null ? BigDecimal.ZERO :shipOrder.getSalesVolume());
            salesStatisticVO.setTrainNum(1);
            salesStatisticVO.setProductSpec(shipOrder.getProductSpec());
            salesStatisticVO.setTaskSn(shipOrder.getTaskSN());
            statisticList.add(salesStatisticVO);
        }
    }
}